#include "qrencode.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>


#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/ioctl.h>

#define X_WIDTH 160
#define Y_WIDTH 160
static void test(const char * str)
{
	printf("Run test\n");
	int cnt=0,i;
	char buf0[1024*1024]={0};
	char buf1[1024*1024]={0};
	char buf[1024*1024]={0};
	int x,y,z=0,z2=0;

	QRcode *qrcode;
	


	//QR_ECLEVEL_L QR_ECLEVEL_M  0x1000堆空间支持QR_ECLEVEL_L 只有':' 和 ' '字符和字母数字可以支持104个字符长边二维码生成，'\r' '\n'等占用大量空间 
	if(str==NULL)
	{
		qrcode = QRcode_encodeString("https://qr.alipay.com/fkx05052lkiwfhclnah3n83", 4, QR_ECLEVEL_L, QR_MODE_8, 0);	
	}	
	else
	{
		qrcode = QRcode_encodeString(str, 4, QR_ECLEVEL_L, QR_MODE_8, 0);	
	}
	
	printf("width=%d\n",qrcode->width);


	// 下面这个是放大二维码的,可以研究一下图片的缩放
	// int buf0_cnt=0;
	// int width, height;
	// {
	// 	int x,y,x1,y1,k,z;
	// 	int xpos, ypos;
		
	// 	k=1;
	// 	// if(X_WIDTH > qrcode->width)
	// 	// {
	// 	// 	k = X_WIDTH/qrcode->width;
	// 	// }
	// 	// else
	// 	// {
	// 	// 	k = 1;
	// 	// }
			
	// 	// if(Y_WIDTH > qrcode->width)
	// 	// {	
	// 	// 	if(k > Y_WIDTH/qrcode->width)
	// 	// 		k = Y_WIDTH/qrcode->width;
	// 	// }
	// 	// else
	// 	// {
	// 	// 	k = 1;
	// 	// }
			
	
	// 	width = qrcode->width * k;
	// 	height = qrcode->width * k;
	// 	xpos = (X_WIDTH - qrcode->width*k) / 2;				//居中显示用	X起始坐标
	// 	ypos = (Y_WIDTH - qrcode->width*k) / 2;				//居中显示用	Y起始坐标
	// 	for (y = 0; y < height; y++)
	// 	{
	// 		for (x = 0; x < width; x++)
	// 		{
	// 			if (qrcode->data[y/k*qrcode->width + x/k] & 0x01)
	// 			{
	// 				buf0[buf0_cnt++]=1;
	// 			}
	// 			else
	// 			{
	// 				buf0[buf0_cnt++]=0;
	// 			}
				
	// 		}
	// 	}


		
	// }



	// for(i=0;i<20;i++)
	// {
	// 	printf("%02x ",buf0[i]);
	// }
	// printf("\n");
	// for(i=0;i<20;i++)
	// {
	// 	printf("%02x ",qrcode->data[i]);
	// }
	// printf("\n");






	// 打印到stdout
	for (y = 0; y < qrcode->width; y++)
	{
		for (x = 0; x < qrcode->width; x++)
		{
			if (qrcode->data[y*qrcode->width + x] & 0x01)
			{
				printf("$");
			}
			else
			{
				printf(" ");
			}
		}
		printf("\n");
	}
	sleep(1);	// 这里因为我的fb驱动会打印,先打印二维码 再触发fb

	char* bb=qrcode->data;
	//  char* bb=buf0;qrcode->width=width;
	printf("pic width=%d\n",qrcode->width);



	
	for(y=0;y<160;y++)
	{
		if(y<qrcode->width)
		{
			for(x=0;x<160;x++)
			{
				if(x<qrcode->width)
				{
					if(bb[z2++]&0x01)//qrcode->data[z2++])
					{
						buf1[z++]=1;
					}	
					else
					{
						buf1[z++]=0;
					}
				}
				else
				{
					buf1[z++]=0;
				}	
			}
		}
		else
		{
			buf1[z++]=0;
		}
	}


	z=0;
	cnt=0;
	for(y=0;y<160;y++)
	{
		for(x=0;x<160/8;x++)
		{
			buf[cnt]=0;
			for(i=0;i<8;i++)
			{
				if(buf1[z++])
				{
					buf[cnt]|=1<<(7-i);
				}
				// buf[cnt]<<=1;

			}
			cnt++;
		}
	}



#ifndef __arm__
	return ;
#endif



    char fbDev[]="/dev/fb0";

    char* fb_o=fbDev;


    int fp = open (fb_o, O_RDWR);
    if (fp < 0){
        printf("Error : Can not open framebuffer device %s \n",fb_o);
        exit(1);
    }
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;

    if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){
        printf("Error reading fixed information\n");
        exit(1);
    }

    if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
        printf("Error reading variable information\n");
        exit(1);
    }

    long screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
    /*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来，得到一个指向这块空间的指针*/
    char *fbp =(char *) mmap (0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
    // if ((int) fbp == -1){
	if (fbp == NULL){
        printf ("Error: failed to map framebuffer device to memory.\n");
        exit (1);
    }
    memset(fbp,0,screensize);

    for ( i = 0; i < cnt; i++)
    {
        *fbp++=buf[i];
    }
    munmap (fbp, screensize); /*解除映射*/
    close (fp);    /*关闭文件*/
		
	
	QRcode_free(qrcode);
	
	

}


int main(int argc, char const *argv[])
{
    /* code */
	while(1)
	{
		test("123");
		sleep(5);
		test("456");
		sleep(5);
		test(NULL);
		sleep(5);
	}

    return 0;
}
